package com.yyge.controller.admin.login;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yyge.common.constans.RedisConstans;
import com.yyge.common.enums.AckCode;
import com.yyge.common.exception.ServiceException;
import com.yyge.common.util.TokenUtil;
import com.yyge.common.util.WaimaiThreadLocal;
import com.yyge.common.vo.resp.R;
import com.yyge.controller.admin.login.req.AdminLoginReq;
import com.yyge.controller.admin.login.resp.AdminLoginResp;
import com.yyge.entity.Employee;
import com.yyge.entity.Merchandiser;
import com.yyge.service.EmployeeService;
import com.yyge.service.MerchandiserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Objects;

/**
 * @Desc： 后台登录实现
 * @Author: admin
 * @Date: 2023/06/29/14:25
 */
@Api(tags = "管理后台-登录")
@RestController
@RequestMapping("/api")
public class AdminLoginController {
    /**
     * 后台管理员
     */
    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private MerchandiserService merchandiserService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 令牌加密、解密操作
     */
    @Autowired
    private TokenUtil tokenService;

    /**
     * 登录 (如何实现同一个用户账户只允许输入错误次数3次，时间范围在30分钟之内，超过3次，账户禁定30分钟)
     *      同一个账户只允许登录一次(如何来实现?)
     * @param req
     * @return
     */
    @ApiOperation(value = "登录")
    @PostMapping(value = "/login")
    public R<String> login(@RequestBody @Valid AdminLoginReq req) {

        String redisKey = RedisConstans.getRedisKey(RedisConstans.CAPTCHA_KEY, req.getUuid());
        Object redisValue = this.redisTemplate.opsForValue().get(redisKey);


        //删除验证码
        this.redisTemplate.delete(redisKey);
        if (Objects.isNull(redisValue)) {
            return R.build(AckCode.SMS_CODE_OVERTIME);
        }

        if (!redisValue.toString().equalsIgnoreCase(req.getCode())) {
            return R.build(AckCode.SMS_CODE_WRONG);
        }

        //管理员登录
        AdminLoginResp adminLoginResp=userLogon(req);

        //----
        //WaimaiThreadLocal.loginVOThreadLocal.set(adminLoginResp);

        //管理员对象存储到redis中，再返回令牌，再令牌进行jwt加密
        String jwtToken=this.tokenService.createJwtToken(adminLoginResp);

        System.out.println("=================");
        System.out.println(jwtToken);
        System.out.println(WaimaiThreadLocal.getCurrent());

        return R.okHasData(jwtToken);
    }

    /**
     * 后台员工登录
     * @param req
     * @return
     */
    private AdminLoginResp  userLogon(AdminLoginReq req){
        //支持 Lambda 形式调用：通过 Lambda 表达式，方便的编写各类查询条件，无需再担心字段写错
        LambdaQueryWrapper<Employee> employeeWrapper=new LambdaQueryWrapper<>();
        employeeWrapper.eq(Employee::getLoginName, req.getLoginName());
        Employee employeedb = this.employeeService.getOne(employeeWrapper);

        AdminLoginResp adminLoginResp =new AdminLoginResp();
        boolean correct=false;
         String status = "0";
        if(employeedb==null){
            LambdaQueryWrapper<Merchandiser> merchandiserWrapper=new LambdaQueryWrapper<>();
            merchandiserWrapper.eq(Merchandiser::getPhone, req.getLoginName());
            Merchandiser merchandiserdb = this.merchandiserService.getOne(merchandiserWrapper);
            if(merchandiserdb==null){
                throw new ServiceException(AckCode.USER_PASSWORD_NOT_FOUND);
            }else{
                //md5增强版 bcrypt --> Hutool工具类实现的 密码
                correct= BCrypt.checkpw(req.getLoginPwd(), merchandiserdb.getLoginPwd());
                if(!correct){
                    throw new ServiceException(AckCode.USER_PASSWORD_NOT_FOUND);
                }
                adminLoginResp.setId(merchandiserdb.getId());
                adminLoginResp.setAvatar(merchandiserdb.getPicture());
                adminLoginResp.setName(merchandiserdb.getName());
                adminLoginResp.setLoginName(merchandiserdb.getPhone());
                adminLoginResp.setType(2);
                status = merchandiserdb.getStatus();
            }
        }else{
            correct= BCrypt.checkpw(req.getLoginPwd(), employeedb.getLoginPwd());
            if(!correct){
                throw new ServiceException(AckCode.USER_PASSWORD_NOT_FOUND);
            }
            adminLoginResp.setId(employeedb.getId());
            adminLoginResp.setName("后台管理员");
            adminLoginResp.setLoginName(employeedb.getLoginName());
            adminLoginResp.setAvatar(employeedb.getAvatar());
            adminLoginResp.setType(1);
            status = employeedb.getStatus();
        }


        //状态
        if(status.equals("1")){
            throw new ServiceException(AckCode.LOGIN_BANNED);
        }
        return adminLoginResp;
    }


    @ApiOperation(value = "获取登录信息")
    @GetMapping(value = "/user/info")
    public R<AdminLoginResp> userInfo(){
        return R.okHasData( WaimaiThreadLocal.getCurrent());
    }

    @ApiOperation(value = "登出")
    @PostMapping(value = "/logout")
    public R<String> logout(){
        AdminLoginResp current = WaimaiThreadLocal.getCurrent();
        this.tokenService.removeRedisLoginVO(current.getToken());
        return R.ok();
    }
}
